package net.sxnic.ugr.security;

import java.util.List;
import java.util.Map;
import java.util.Set;

import net.sxinfo.core.entity.EntityAlreadyExistsException;
import net.sxnic.ugr.group.Group;
import net.sxnic.ugr.menu.Menu;
import net.sxnic.ugr.permission.Permission;
import net.sxnic.ugr.role.Role;
import net.sxnic.ugr.user.User;

import org.springframework.transaction.annotation.Transactional;

/**
 * Authorization Manager
 * 
 * @version $Revision$
 * @author 
 */
@Transactional
public interface AuthorizationManager {

    /**
     * 配置文件中的角色前缀，用来标识角色
     */
    static final String ROLE_PREFIX = "ROLE_";

    /**
     * 当所有权限都通过
     */
    static final String IF_ALL_GRANTED = "ifAllGranted";

    /**
     * 当任意权限通过
     */
    static final String IF_ANY_GRANTED = "ifAnyGranted";

    /**
     * 当没有权限被通过
     */
    static final String IF_NOT_GRANTED = "ifNotGranted";

   
    /**
     * 获取角色代码对应的角色对象
     *
     * @param role 角色代码
     * @return
     */
    Role getRole(String role);
    
    /**
     * 获取用户代码对应的用户对象
     *
     * @param username 用户登录名
     * @return
     */
    User getUser(String username);
    
    /**
     * 获取用户组代码对应的用户组对象
     *
     * @param name 用户组名
     * @return
     */
    Group getGroup(String name);
    
    /**
     * 获取权限名称对应的权限对象
     *
     * @param name 权限名称
     * @return
     */
    Permission getPermission(String name);

    /**
     * 根据id获取角色
     *
     * @param id id
     * @return Role
     */
    Role getRoleById(String id);
    
    
    /**
     * 根据id获取角色权限对象
     *
     * @param id id
     * @return
     */
    Permission getPermissionById(String id);

    /**
     * 获取全部角色列表
     *
     * @return 全部角色列表
     */
    List<Role> getRoles();
    
    /**
     * 获取全部用户列表
     *
     * @return 全部用户列表
     */
    List<User> getUsers();
    
    /**
     * 获取全部用户组列表
     *
     * @return 全部用户组列表
     */
    List<Group> getGroups();
    
    /**
     * 获取全部权限列表
     *
     * @return 全部权限列表
     */
    List<Permission> getPermissions();
    
    
    
    /**
     * 获取全部菜单列表
     *
     * @return 全部菜单列表
     */
    List<Menu> getMenus();


    /**
     * 获取指定角色的用户列表
     *
     * @param role 角色
     * @return 具有指定角色的用户列表
     */
    List<User> getUsersInRole(Role role);
    
    /**
     * 获取指定角色的用户列表
     *
     * @param role 角色代码
     * @return 具有指定角色的用户列表
     */
    List<User> getUsersInRole(String roleCode);
    
    /**
     * 获取指定角色的用户列表
     *
     * @param role 角色
     * @return 具有指定角色的用户列表
     */
    List<User> getUsersInGroup(Group group);
    
    /**
     * 获取指定角色的用户列表
     *
     * @param role 角色代码
     * @return 具有指定角色的用户列表
     */
    List<User> getUsersInGroup(String groupCode);
    

    /**
     * 获取指定角色的组列表
     *
     * @param role 角色
     * @return 具有指定角色的组列表
     */
    List<Group> getGroupsInRole(Role role);
    
    /**
     * 获取指定角色的组列表
     *
     * @param role 角色代码
     * @return 具有指定角色的组列表
     */
    List<Group> getGroupsInRole(String roleCode);

    /**
     * 创建一个角色
     *
     * @param role 角色对象
     * @throws EntityAlreadyExistsException 当相同的角色代码已经存在的时候抛出
     */
    void createRole(Role role) throws EntityAlreadyExistsException;

    /**
     * 删除角色
     *
     * @param role 要删除的角色
     */
    void deleteRole(Role role);

    /**
     * 更新角色
     *
     * @param role 要更新的角色
     */
    void updateRole(Role role);
    
    /**
     * 更新用户组
     *
     * @param role 要更新的用户组
     */
    void updateGroup(Group group);
    
    /**
     * 删除用户组
     *
     * @param role 要删除的用户组
     */
    void deleteGroup(Group group);
    
    /**
     * 创建一个权限
     *
     * @param Permission 权限对象
     * @throws EntityAlreadyExistsException 当相同的权限代码已经存在的时候抛出
     */
    void createPermission(Permission permission) throws EntityAlreadyExistsException;
    
    /**
     * 删除权限
     *
     * @param role 要删除的权限
     */
    void deletePermission(Permission permission);
    
    /**
     * 更新权限
     *
     * @param role 要更新的权限
     */
    void updatePermission(Permission permission);
    

    /**
     * 赋予用户角色
     * 
     * @param user 要授权的用户
     * @param role 要授予的角色
     */
    void grantRole(User user, String role);

    /**
     * 赋予用户角色
     * 
     * @param user 要授权的用户
     * @param role 要授予的角色
     */
    void grantRole(User user, Role role);

    /**
     * 删除用户的指定角色
     * 
     * @param user 要操作的用户
     * @param role 要删除的角色
     */
    void revokeRole(User user, String role);

    /**
     * 删除用户的指定角色
     * 
     * @param user 要操作的用户
     * @param role 要删除的角色
     */
    void revokeRole(User user, Role role);

    /**
     * 赋予组角色
     * 
     * @param group 要授权的组
     * @param role 要授予的角色
     */
    void grantRole(Group group, String role);

    /**
     * 赋予组角色
     * 
     * @param group 要授权的组
     * @param role 要授予的角色
     */
    void grantRole(Group group, Role role);

    /**
     * 删除组的指定角色
     * 
     * @param group 要操作的组
     * @param role 要删除的角色
     */
    void revokeRole(Group group, String role);

    void revokeRole(Group group, Role role);

    /**
     * 确定一个用户是否为指定角色
     * 
     * @param user 要确定的用户
     * @param role 需要的角色
     * @return 如果用户是指定角色就返回true
     */
    @Transactional(readOnly = true)
    boolean isUserInRole(User user, String role);

    /**
     * 确定一个组是否为指定角色
     * 
     * @param group 要确定的组
     * @param role 需要的角色
     * @return 如果组是指定角色就返回true
     */
    @Transactional(readOnly = true)
    boolean isGroupInRole(Group group, String role);

    /**
     * 确定一个用户及所属的组是否为指定角色
     * 
     * @param user 要确定的用户
     * @param role 需要的角色
     * @return 如果用户是指定角色就返回true
     */
    @Transactional(readOnly = true)
    boolean isUserGroupInRole(User user, String role);

    /**
     * 从UserContext中取得User对象，然后对用户所具有的角色进行判断。
     * 用户具有roles中所要求的任意角色就返回true，如果用户具有admin的角色，那么他就相当于具有全部角色
     * 
     * @param rule 判断规则，可以是ifAllGranted, ifAnyGranted, ifNotGranted
     * @param roles 要求的角色名称
     * @return 用户具有roles中所要求的任意角色就返回true
     */
    @Transactional(readOnly = true)
    boolean isInRole(String rule, String... roles);
    
    /**
     * 给角色赋予权限
     * @param role 角色名
     * @param permissionNames 权限名数组
     */
    void addRolePermission(String role,String... permissionNames);
    
    /**
     * 给角色赋予权限
     * @param role 角色
     * @param permissionNames 权限
     */
    void addRolePermission(Role role,Permission permission);
    
    /**
     * 移除角色中的指定权限
     * @param role 角色名
     * @param permissionNames 权限名数组
     */
    void removeRolePermission(String role,String... permissionNames);
    
    /**
     * 查询指定用户名的权限列表
     * @param userName 用户名
     * @return 权限列表
     */
    @Transactional(readOnly = true)
    Set<Permission> findUsersPermission(String userName);
   
    
    /**
     * 验证指定用户可否访问指定的资源（URL）
     * @param userName 用户名
     * @param res 资源（URL）
     * @return 如果可以访问返回true，否则返回false
     */
    @Transactional(readOnly = true)
    boolean isUserCanAccessResource(String userName,String res);
    
    /**
     * 查询指定用户名的菜单列表
     * @param userName 用户名
     * @return 菜单列表
     */
    @Transactional(readOnly = true)
    Set<Menu> findMenus(String userName);
    
    
    /**
     * 查询指定用户名的菜单列表
     * @param userName 用户名
     * @return 菜单列表
     */
    Map<String, String> findUserMenu(String userName);
    
    
    /**
	 * 获取顶级菜单（即所有一级菜单）
	 * 
	 * @return
	 */
	List<Menu> getTopLevel();
	
	/**
	 * 根据菜单码查询其下一级的所有菜单
	 * 
	 * @param parentMenuCode
	 *            菜单码
	 * @return
	 */
	List<Menu> getSubLevel(String parentMenuCode);

    
    
    
    /**
     * 查询指定编码的菜单对象
     * @param code 编码
     * @return 菜单对象
     */
     
     Menu getMenu(String code);
    
    /**
     * 验证指定用户是在组里
     * @param user 用户
     * @param groupName 组名
     * @return 
     */
    @Transactional(readOnly = true)
    boolean isUserInGroup(User user,String groupName);
    
    /**
     * 验证指定用户是在组里
     * @param user 用户
     * @param groupName 组名
     * @return 
     */
    @Transactional(readOnly = true)
    boolean isUserInGroup(String user,String groupName);
    
    /**
     * 给角色赋予菜单
     * @param role 角色名
     * @param menus 菜单名数组
     */
    void addRoleMenu(String role,String... menus);

}
